/*
The "val" version returns the contents of
     `*PTR' before the operation.
These builtins perform an atomic compare and swap.  That is, if
     the current value of `*PTR' is OLDVAL, then write NEWVAL into
     `*PTR'.

*/

volatile int __my_lock__=0;
unsigned int compare_and_swap(int  *mem, int old, int new)
{
#ifdef TARG_SW5
  unsigned int __addr,__prev,__cmp;
  int  __tmp;
  __asm__ __volatile__(
      "        memb\n"
      "        ldi	%3,%5\n"
      "1:      faaw     %2,0(%3)\n"
      "        bne      %2,1b\n"
      "        memb\n"
      "        ldw      %0,%4\n"
      "        cmpeq    %0,%6,%1\n"
      "        beq      %1,2f\n"
      "        mov      %7,%1\n"
      "        stw      %1,%4\n"
      "        mov      1,%1\n"
      "2:      memb\n"
      "        mov      %0,%2\n"
      "        stw      $31,0(%3)\n"
      "        memb\n"
      : "=&r"  (__prev),
        "=&r"  (__cmp),
        "=&r"  (__tmp),
        "=&r"  (__addr)
      : "m" (*(mem)),
        "m" (__my_lock__),
        "Ir" ((unsigned long)(old)),
        "Ir" (new)
      : "memory");
    return __tmp;
#elif TARG_SW9
   assert(0);
#endif
}
